package com.alfresco.extension.invitation;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PermissionService;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;

/**
 * 
 * @author Rui Fernandes
 * 
 */
public class Authentication extends DeclarativeWebScript {

	private MutableAuthenticationService authenticationService;
	private AuthorityService authorityService;
	private List<String> allowedGroupsList;

	public void setAllowedGroups(String allowedGroups) {
		this.allowedGroupsList = Arrays
				.asList(allowedGroups.split("\\s*,\\s*"));
		;
	}

	public void setAuthenticationService(
			AuthenticationService authenticationService) {
		this.authenticationService = (MutableAuthenticationService) authenticationService;
	}

	public void setAuthorityService(AuthorityService authorityService) {
		this.authorityService = authorityService;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco
	 * .web.scripts.WebScriptRequest,
	 * org.alfresco.web.scripts.WebScriptResponse)
	 */
	@Override
	protected Map<String, Object> executeImpl(WebScriptRequest req,
			Status status) {
		String user = authenticationService.getCurrentUserName();
		Map<String, Object> model = new HashMap<String, Object>(2);

		model.put("creationAllowed",
				this.authenticationService.isAuthenticationCreationAllowed()
						&& isUserAllowedToInvite(user));

		return model;
	}

	private boolean isUserAllowedToInvite(String user) {
		if (allowedGroupsList == null || allowedGroupsList.size() == 0)
			return true;
		for (String group : allowedGroupsList) {
			if (userBelongsToGroup(user, group))
				return true;
		}
		return false;
	}

	private boolean userBelongsToGroup(String user, final String group) {
		// bellow is how it should be for 4+, but for now we want compatibility to 3.4
		/*
		 * Set<String> users = AuthenticationUtil .runAsSystem(new
		 * AuthenticationUtil.RunAsWork<Set<String>>() {
		 * 
		 * public Set<String> doWork() throws Exception {
		 * 
		 * return authorityService.getContainedAuthorities( AuthorityType.USER,
		 * PermissionService.GROUP_PREFIX + group, true);
		 * 
		 * }
		 * 
		 * });
		 */
		try {
			AuthenticationUtil.setRunAsUserSystem();
			Set<String> users = authorityService.getContainedAuthorities(
					AuthorityType.USER, PermissionService.GROUP_PREFIX + group,
					true);
			return users.contains(user);
		} finally {
			AuthenticationUtil.setRunAsUser(user);
		}
	}

}
